#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2017/5/16 15:50
# @Author  : Leixu
# @Site    : 
# @File    : tornado_http_client.py
# @Software: PyCharm Community Edition
from multiprocessing import Event

import tornado
from tornado import gen
from tornado.concurrent import Future
from tornado.httpclient import *


class TornadoHttpClient(object):
    def __init__(self, url, end_event: Event, response_list=[]):
        self.response_list = response_list
        self.url = url
        self.MAX_CONCURRENT_REQUESTS = 50
        self.end_event = end_event
        self.running_request_list: [Future] = []
        self.client = AsyncHTTPClient(max_clients=self.MAX_CONCURRENT_REQUESTS * 2)

    @gen.coroutine
    def fetch(self, url, method="GET"):
        client = AsyncHTTPClient()
        request = HTTPRequest(url, method=method, connect_timeout=10 * 60,
                              request_timeout=10 * 60)
        self.running_request_list.append(client.fetch(request, self.nromal_callback))

    @gen.coroutine
    def run(self):
        self.fetch(self.url)
        IOLoop.current().spawn_callback(self.watch_dog, self.done)

    def done(self):
        # 通知处理已经结束了请求
        self.end_event.set()
        print("EveryThing one")

    @gen.coroutine
    def watch_dog(self, callback):
        while True:
            yield gen.sleep(0.010)
            self.clear_done_task()
            if len(self.running_request_list) > 0:
                continue
            else:
                break
        return callback()

    def clear_done_task(self):
        self.running_request_list = list(filter(lambda x: x.running(), self.running_request_list))

    def nromal_callback(self, response: HTTPResponse):
        self.responese_list.append(response)


@gen.coroutine
def main(url, response_list=[]):
    end_event = Event()
    thc = TornadoHttpClient(url, end_event, response_list)
    thc.run()
    while True:
        if end_event.is_set():
            return thc.responese_list
        else:
            # 协程睡眠
            yield gen.sleep(0.001)


def run_this_by_threading(url):
    response_list = []
    io_loop = tornado.ioloop.IOLoop.current()
    io_loop.run_sync(lambda: main(url, response_list=response_list))
    return response_list
